package cn.demoncat.util.web.util;

import cn.demoncat.util.lang.CompletableFutureUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

/**
 * 异步工具
 *
 * 1、使用默认的AsyncExecutor，执行CompletableFuture异步操作
 *
 * whenComplete()：执行完成（成功或异常）回调（由任务线程执行）
 * whenCompleteAsync()：执行完成（成功或异常）回调（由新线程执行）
 * exceptionally()：发生异常回调，可以修改返回值
 * handle()：添加串行任务（成功或异常），返回结果
 * thenApply()：添加串行任务（成功），返回结果
 * thenAccept()：串行执行任务，有消费，无返回
 * thenRun()：串行执行任务，无消费，不返回
 * get()：阻塞等待执行完成，抛出ExecutionException
 * join()：阻塞等待执行完成，抛出CompletionException（RuntimeException）
 *
 * 执行完成：whenComplete()
 *
 * @author 延晓磊
 * @since 2021年02月18日
 */
@Component
public class AsyncUtil extends CompletableFutureUtil {

    @Resource
    private Executor asyncExecutor;

    /**
     * 创建异步执行任务（异步执行，非阻塞）
     *
     * @param runnable  无返回的任务
     * @return
     *
     * @author 延晓磊
     * @since 2021年02月18日
     */
    public CompletableFuture<Void> run(Runnable runnable) {
        return build(runnable, asyncExecutor);
    }

    /**
     * 创建异步执行任务（异步执行，非阻塞）
     *
     * @param supplier  有返回的任务
     * @return
     *
     * @author 延晓磊
     * @since 2021年02月18日
     */
    public <U> CompletableFuture<U> run(Supplier<U> supplier) {
        return build(supplier, asyncExecutor);
    }

    /**
     * 批量异步执行（异步执行，阻塞等待全部完成）
     *
     * @param runnable
     *
     * @author 延晓磊
     * @since 2021年02月18日
     */
    public void runs(Runnable ...runnable){
        async(asyncExecutor, runnable);
    }

    /**
     * 批量异步执行（异步执行，阻塞等待全部完成）
     *
     * @param runnable
     *
     * @author 延晓磊
     * @since 2021年02月18日
     */
    public void runs(List<Runnable> runnable){
        async(asyncExecutor, runnable);
    }
}
